package com.zkh360.service.message.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.zkh360.service.message.constant.ErrorCode;
import com.zkh360.service.message.domain.SysAuthorities;
import com.zkh360.service.message.domain.SysAuthoritiesResources;
import com.zkh360.service.message.domain.SysResources;
import com.zkh360.service.message.exceptions.BusinessException;
import com.zkh360.service.message.mapper.AuthoritiesMapper;
import com.zkh360.service.message.mapper.AuthoritiesResourceMapper;
import com.zkh360.service.message.mapper.ResourcesMapper;
import com.zkh360.service.message.model.Pager;
import com.zkh360.service.message.model.SysAuthoritiesResourcesVO;
import com.zkh360.service.message.model.SysAuthorityVO;
import com.zkh360.service.message.model.SysResourcesVO;
import com.zkh360.service.message.model.SysUserVO;
import com.zkh360.service.message.service.ResourceService;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 
 * @author chuanxi.zhao
 *
 */
@Service(value = "ResourceService")
@Slf4j
public class ResourceServiceImpl implements ResourceService {

	@Autowired
	private ResourcesMapper resourcesMapper;

	@Autowired
	private AuthoritiesResourceMapper authoritiesResourceMapper;
	
	@Autowired
	private AuthoritiesMapper authoritiesMapper;

	@Override
	public List<SysResourcesVO> getResources(SysResourcesVO sysResources) throws BusinessException {

		SysResources sysUsersParams = new SysResources();
		sysUsersParams.setResource_name(sysResources.getResource_name());
		sysUsersParams.setResource_level(sysResources.getResource_level());
		sysUsersParams.setResource_id(sysResources.getResource_id());
		List<SysResources> sysResourceList = resourcesMapper.select(sysUsersParams);
		List<SysResourcesVO> SysResourceVoList = new ArrayList<>();
		sysResourceList.stream().forEach(sysResource -> {
			SysResourcesVO sysResourceTemp = new SysResourcesVO();
			BeanUtils.copyProperties(sysResource, sysResourceTemp);
			SysResourceVoList.add(sysResourceTemp);
		});

		return SysResourceVoList;
	}

	@Override
	public List<SysResourcesVO> getResourcesByUser(SysUserVO sysUsers, Integer enabled, Pager pager) throws BusinessException {
		
		return resourcesMapper.getResourcesByUser(sysUsers.getUser_id(), 
				sysUsers.getUser_account(), enabled, pager.getStartRow(), pager.getPageSize());
	}

	@Override
	public void addResource(SysResourcesVO sysResourcesVo) throws BusinessException {
		try {
			// 转成
			SysResources sysResources = new SysResources();
			BeanUtils.copyProperties(sysResourcesVo, sysResources);
			if (sysResourcesVo.getParent_id() == 0) {
				sysResources.setResource_level(1);
			} else {
				sysResources.setResource_level(2);
			}
			// 设置排序
			int count = resourcesMapper.selectCount(new SysResources());
			sysResources.setResource_order(count + 1);
			resourcesMapper.insert(sysResources);
		} catch (Exception e) {
			log.error("存储菜单消息失败：" + e.getMessage());
			throw BusinessException.customException(ErrorCode.CODE_FAILURE, "存储菜单消息失败");
		}

	}

	@Override
	public List<SysResourcesVO> getResourcesByAuthority(SysAuthorityVO sysAuthorityVo) {
		return resourcesMapper.getResourcesByAuthority(sysAuthorityVo.getAuthority_id());
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
	public void editResourceByAuthority(List<SysAuthoritiesResourcesVO> authorityResourcesVoList) {
		// 清除原来的客户权限资源信息
		SysAuthoritiesResources sysAuthorityResourceParams = new SysAuthoritiesResources();
		sysAuthorityResourceParams.setAuthority_id(authorityResourcesVoList.get(0).getAuthority_id());
		authoritiesResourceMapper.delete(sysAuthorityResourceParams);
		// 查询所有资源数据，方便后面找到父节点
		List<SysResources> allResources = resourcesMapper.selectAll();
		Map<Integer, SysResources> resourceMap = new HashMap<>();
		allResources.forEach(resources -> {
			resourceMap.put(resources.getResource_id(), resources);
		});
		
		Set<Integer> parentIdSet = new HashSet<>();
		List<SysAuthoritiesResources> sysAuthoritiesResourcesList = new ArrayList<>();
		authorityResourcesVoList.forEach(authorityResourcesVo -> {
			SysAuthoritiesResources temp = new SysAuthoritiesResources();
			temp.setResource_id(authorityResourcesVo.getResource_id());
			temp.setAuthority_id(authorityResourcesVo.getAuthority_id());
			temp.setEnabled(authorityResourcesVo.getEnabled());
			sysAuthoritiesResourcesList.add(temp);
			parentIdSet.add(resourceMap.get(authorityResourcesVo.getResource_id()).getParent_id());
		});
		// 设置父菜单
		parentIdSet.forEach(parentId -> {
			SysAuthoritiesResources temp = new SysAuthoritiesResources();
			temp.setResource_id(resourceMap.get(parentId).getResource_id());
			temp.setAuthority_id(authorityResourcesVoList.get(0).getAuthority_id());
			temp.setEnabled(1);
			sysAuthoritiesResourcesList.add(temp);
		});
		authoritiesResourceMapper.insertList(sysAuthoritiesResourcesList);
	}

	@Override
	public void deleteResource(Integer resourceId) {
		// 需要加逻辑判断，确定所有的权限都没有关联到该资源才能停用该资源
		List<SysAuthorities> authorities = authoritiesMapper.getAuthorityByResourceId(resourceId, 1);
		if(authorities.size() > 0) {
			throw BusinessException.customException(ErrorCode.CODE_FAILURE, "存在权限配置该资源，无法删除");
		}else {
			SysResources searchParams = new SysResources();
			searchParams.setResource_id(resourceId);
			SysResources sysResources = resourcesMapper.selectOne(searchParams);
			sysResources.setEnabled(0);
			resourcesMapper.updateByPrimaryKey(sysResources);	
		}
	}

	@Override
	public void editResource(SysResourcesVO sysResourcesVo) {
		//
		if (sysResourcesVo.getParent_id() == 0) {
			sysResourcesVo.setResource_level(1);
		} else {
			sysResourcesVo.setResource_level(2);
		}
		SysResources searchParams = new SysResources();
		searchParams.setResource_id(sysResourcesVo.getResource_id());
		SysResources sysResourceFromDB = resourcesMapper.selectOne(searchParams);
		
		if(sysResourceFromDB == null) {
			throw BusinessException.customException(ErrorCode.CODE_FAILURE, "查询不到该菜单信息");
		}else {
			sysResourceFromDB.setEnabled(sysResourcesVo.getEnabled());
			sysResourceFromDB.setIssys(sysResourcesVo.getIssys());
			sysResourceFromDB.setParent_id(sysResourcesVo.getParent_id());
			sysResourceFromDB.setResource_desc(sysResourcesVo.getResource_desc());
			sysResourceFromDB.setResource_level(sysResourcesVo.getResource_level());
			sysResourceFromDB.setResource_name(sysResourcesVo.getResource_name());
			sysResourceFromDB.setResource_String(sysResourcesVo.getResource_String());
			sysResourceFromDB.setResource_type(sysResourcesVo.getResource_type());
			resourcesMapper.updateByPrimaryKey(sysResourceFromDB);
		}
		
	}

	@Override
	public int getResourceCount(SysUserVO sysUsersVo) {
		return resourcesMapper.getResourceCount(sysUsersVo);
	}

}
